home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / Dots & Pixels / headers / vretrace.h < prev    next >
C/C++ Source or Header  |  1995-09-29  |  5KB  |  146 lines

  1. #pragma once
  2. //
  3. // Note: instances of class 'vretrace should _never_ be allocated on a relocatable block!
  4. // It also is unadvisory to forget to call 'stop' for an instance of vretrace for which
  5. // 'start' has been called. If that is done the VBL routine will be called after the
  6. // program which installed it has quit. This will sooner or later crash your machine.
  7. //
  8. // 950330:
  9. // 
  10. // In article <jens_alfke-2803951102300001@jensothermac.apple.com>, jens_alfke@powertalk.apple.com (Jens Alfke) wrote:
  11. // 
  12. // > In article <kastork-2803950428450001@slb140.cc.nps.navy.mil>,
  13. // > kastork@nps.navy.mil (Kirk A. Stork) wrote:
  14. // > 
  15. // > > Don't constructors have to be public?
  16. // > 
  17. // > No. A protected or private constructor is useful, as it prevents just
  18. // > anyone from creating an object of that class. If it's private, only a
  19. // > method of the class can create new objects (presumably you need a public
  20. // > static method to create the first one!). If it's protected, you can create
  21. // > subclasses that have public constructors.
  22. // > Similarly, you can make a class' operator new private, which prevents it
  23. // > from being allocated on the heap.
  24. // >
  25. // >
  26. // > Jens Alfke_________OpenDoc Geometer_________jens_alfke@powertalk.apple.com
  27. // >                                            OpenDoc info: FTP to CILabs.org
  28. // >
  29. // >          Visit Scenic Flood Control Dam No. 3.
  30. //
  31. // This is something to be implemented in the future.
  32. //
  33. // 940204: Although the destructor does call 'stop' when needed programs using
  34. // multiple vretrace instances do 'enter MacsBug' (some people call that 'crash')
  35. // regularly with a message 'spurious interrupt'. I am not sure whether this is due
  36. // to class vretrace, but calling 'stop()' for every start instance seems to prevent
  37. // these visits to MacsBug. A hunch tells me that SC++ occasionaly optimizes out
  38. // or forgets to call the (inline) destructor calls.
  39. //
  40. // BUG ALERT    BUG ALERT    BUG ALERT    BUG ALERT    BUG ALERT    BUG ALERT    BUG ALERT
  41. //
  42. // 950814: KNOWN BUG: the constructor vretrace::vretrace( const short how_often)
  43. // assumes that the current graphics device belongs to a physical screen and has
  44. // a vertical retrace queue associated with it. It uses the current graphics port
  45. // to determine for which device the vertical retrace task should be installed.
  46. //
  47. // BUG ALERT    BUG ALERT    BUG ALERT    BUG ALERT    BUG ALERT    BUG ALERT    BUG ALERT
  48. //
  49. #ifndef __CONDITIONALMACROS__
  50.     #define VBLUPP VBLProcPtr
  51.     #define NewRoutineDescriptor(theProc, theProcInfo, theISA) (theProc)
  52. #endif
  53.  
  54. double framerate_of_main_monitor( void);
  55. double monitor_framerate( GDHandle the_gDevice);
  56.  
  57. #pragma options align=mac68k
  58.  
  59. class vretrace
  60. {
  61.     public:
  62.         //
  63.         // defaults: main monitor (often the only one)
  64.         //
  65.         vretrace( const short how_often = 1);
  66.         vretrace( GDHandle thegDevice, const short how_often = 1);
  67.         
  68.         ~vretrace();
  69.         int start();        // returns error code from SlotVInstall
  70.         int stop();            // returns error code from SlotVRemove
  71.  
  72.         void set_interval( const short new_interval);
  73.         //
  74.         // reset() resets the counter and returns its old value;
  75.         //
  76.         unsigned long reset( const unsigned long new_value);
  77.  
  78.         unsigned long operator()();
  79.         //
  80.         // The 'sync' members synchronise on a VBL using a busy loop.
  81.         // The integer returned is the new current value of the counter
  82.         //
  83.         unsigned long sync( const unsigned long count = 1);
  84.         void sync_till( const unsigned long count);
  85.  
  86.         static short getslot( const GDHandle gDev);
  87.         
  88.     private:
  89.         static VBLUPP theVBLProcPtr;
  90.  
  91.         static VBLUPP allocateVBL( void);
  92.         
  93.         int is_running;
  94.         //
  95.         // Note: the following three fields _must_ be kept together in
  96.         //       this order (the VBL proc depends on this)
  97.         //
  98.         // 940211: Finally think I found the bug which was dormant for
  99.         // weeks (and very awake for the last week or so): numtimes_run
  100.         // should be allocated volatile since the VBL proc will change it.
  101.         // (well, it was a bug, but it apparently still was dormant)
  102.         //                                        offset from 'myVBLTask'
  103.         short the_interval;                        //        -0x06
  104.         volatile unsigned long numtimes_run;    //        -0x04
  105.         VBLTask  myVBLTask;                        //        -0x00
  106.         
  107.         short    mySlot;
  108.  
  109.         void init( const short theSlot, const short how_often);
  110. };
  111.  
  112. #pragma options align=reset
  113.  
  114. inline vretrace::vretrace( const short how_often)
  115. {
  116.     init( getslot( GetGDevice()), how_often);
  117. }
  118.     
  119. inline vretrace::vretrace( GDHandle thegDevice, const short how_often)
  120. {
  121.     init( getslot( thegDevice), how_often);
  122. }
  123.  
  124. inline vretrace::~vretrace()
  125. {
  126.     if( is_running)
  127.     {
  128.         (void)stop();
  129.     }
  130. }
  131.  
  132. inline void vretrace::set_interval( const short new_interval)
  133. {
  134.     the_interval = new_interval;
  135. }
  136.  
  137. inline unsigned long vretrace::operator()()
  138. {
  139.     return numtimes_run;
  140. }
  141.  
  142. inline double framerate_of_main_monitor( void)
  143. {
  144.     return monitor_framerate( GetMainDevice());
  145. }
  146.